// Parser.h : Declaration of function prototypes and variables for Parser.cpp
// Author: Heng Belson
//

#ifndef PARSER_H
#define PARSER_H

#include "SPA_Data_Types.h"
#include "AST_Builder.h"

class Parser {
public:
	Parser(AST *ast);
	STATUS Parse(STRING readFromFile);
private:
	struct ST_Statement;
	struct ST_Expression;

	typedef vector<ST_Expression> EXPRESSION_LIST;

	#pragma region Struct Declarations
	/******************************/
	/* Struct Declarations		   /
	/******************************/
	struct ST_StatementList {
		vector<ST_Statement> statement;
	};

	struct ST_Assignment {
		STRING leftVar;
		EXPRESSION_LIST expression;
	};

	struct ST_Call {
		STRING procedureName;
	};

	struct ST_While {
		STRING condition;
		ST_StatementList body;
	};

	struct ST_If {
		STRING condition;
		ST_StatementList thenPart;
		ST_StatementList elsePart;
	};

	struct ST_Statement {
		STATEMENT_TYPE statementType;
		ST_Assignment assignStat;
		ST_If ifStat;
		ST_While whileStat;
		ST_Call callStat;
	};

	struct ST_Procedure {
		STRING name;
		ST_StatementList statementList;
	};

	struct ST_Program {
		STRING name;
		vector<ST_Procedure> procedures;
	};

	struct ST_Variable {
		STRING name;
	};

	struct ST_Constant {
		INTEGER value;
	};

	struct ST_Plus {
		EXPRESSION_LIST leftBranch;
		STRING rightBranch;
	};

	struct ST_Minus {
		EXPRESSION_LIST leftBranch;
		STRING rightBranch;
	};

	struct ST_Times {
		EXPRESSION_LIST leftBranch;
		STRING rightBranch;
	};

	struct ST_Expression {
		EXPRESSION_TYPE exprType;
		ST_Times multiply;
		ST_Plus plus;
		ST_Minus minus;
		ST_Variable variable;
		ST_Constant constant;
	};
	/******************************/
	#pragma endregion

	#pragma region Function Prototypes
	/******************************/
	/* Main functions			   /
	/******************************/
	void Program();
	void Procedure(STRING procedureName);
	ST_StatementList StatementList(ST_StatementList stmtLst);
	ST_StatementList Statement(ST_StatementList stmtLst);
	/******************************/

	/******************************/
	/* Sub functions			   /
	/******************************/
	EXPRESSION_LIST BinaryOperation(STRING expression, EXPRESSION_LIST expr);
	EXPRESSION_LIST EvaluateExpression(STRING eval, EXPRESSION_LIST expr);
	void PopulateTables();
	void Match(TOKEN_LIST token);
	void Scanner(TOKEN_LIST token);
	/******************************/

	/******************************/
	/* Support functions		   /
	/******************************/
	COLLECTION getOperands(STRING expression, STRING op);
	STRING doStatement(ST_StatementList stmtLst);
	STRING doExpression(EXPRESSION_LIST expression, BOOLEAN isReducedExpression);
	BOOLEAN isConstant(STRING expression);
	BOOLEAN isReducible(STRING expression);
	BOOLEAN isFound(TOKEN_LIST token, STRING line);
	BOOLEAN isFound(TOKEN token, STRING line);
	COLLECTION splitAt(STRING word, STRING delimiter);
	/******************************/
	#pragma endregion

	/******************************/
	/* Global Declarations		   /
	/******************************/
	ST_Program program;
	ST_Procedure procedure;

	AST_Builder builder;
	
	PROC_QUEUE p;
	VAR_QUEUE v;

	STRING stream, fileLocation;
	INTEGER offset;
};
#endif